/*

  Copyright (C) 2010  INRIA, Planète Team

  Authors:
  ------------------------------------------------------------
   Amir Krifa                        :  krifa.amir@gmail.com
   Chadi Barakat                     :  Chadi.Barakat@sophia.inria.fr
  ------------------------------------------------------------

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 3
as published by the Free Software Foundation.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

#ifndef ROUTES_H
#define ROUTES_H

#include <string>
#include <map>
#include <list>

using namespace std;

class Handlers;
class Link;
class XMLTree;

typedef struct TemporalRoute 
{
	string eid;
	Link* link;
}TemporalRoute;

class Routes 
{
public:	
	Routes(Handlers* router);
	~Routes();
	
	/**
	 * Called when a "route_delete_event" is received. Removes the mapping
	 * of the EID to the link.
	 *  
	 * @param evtRouteDelete XMLTree object representing the event.
	 */
	void deleteRoute(XMLTree* evtRouteDelete);
	
	/**
	 * Called to process a route_report. The report is requested by HBSD in
	 * the event HBSD starts after dtnd.
	 * 
	 * @param event The root route_report element.
	 */
	void reportReceived(XMLTree* event);
	
	/**
	 * Called to add a temporal route. A temporal route is a created when
	 * a link opens to a particular node. This can be through discovery,
	 * etc. synchronized method.
	 * 
	 * @param eid The EID associated with the link.
	 * @param link The instance of the Link object for the open link.
	 */
	void addTemporalRoute(string eid, Link* link);
	
	/**
	 * Removes a temporal route. synchronized method.
	 * 
	 * @param eid The EID of the temporal route.
	 * @param link The instance of the Link object for the open link.
	 */
	void deleteTemporalRoute(string eid, Link *link);
	
	/**
	 * Gets the link for a given EID. We first look for temporal routes
	 * since they are already open. After that, we search for persistent
	 * routes. We only return a temporal route if it's not associated with
	 * a Node object. synchronized method.
	 * 
	 * @param eid EID to locate.
	 * @param excludeLink Link to exclude from the search (NULL if no 
	 *    exclusions).
	 * @return The link object, or NULL if there is no route.
	 */
	Link *getLink(string eid, Link *excludeLink);
	
	
	/**
	 * Gets the temporal link for a given EID. synchronized method.
	 * 
	 * @param eid EID to locate.
	 * @param excludeLink Link to exclude from the search (NULL if no 
	 *    exclusions).
	 * @param notAssociated If set to true then a link matches on if
	 *    it's not currently associated with a node.
	 * @return The link object, or NULL if there is no route.
	 */
	Link *getTemporalLink(string eid, Link *excludeLink, bool notAssociated);
	

	/**
	 * Gets the temporal link for a given EID. We only return a temporal route
	 * if it's not associated with a Node object.
	 * 
	 * @param eid EID to locate.
	 * @param excludeLink Link to exclude from the search (NULL if no 
	 *    exclusions).
	 * @return The link object, or NULL if there is no route.
	 */
	inline Link *getTemporalLink(string eid, Link *excludeLink) 
	{
		return getTemporalLink(eid, excludeLink, true);
	}

	/**
	 * Called when a "route_add_event" is received. Creates a mapping from
	 * the EID to the link. Note that the event contains a URI, which can
	 * have finer granularity than the EID. But we only support routes that
	 * map an EID to a link. Also note that Node objects are created at the
	 * first reference to an EID, so adding a route may result in a Node
	 * object being created. Finally, note that we expect only a single
	 * route per EID.
	 *  
	 * @param evtRouteAdd XMLTree object representing the event.
	 */	
	void addRoute(XMLTree* evtRouteAdd); 
protected:
	Handlers *router;
	
	

private:
	/**
	 * Simplistic parser to return the EID from a URI. For our
	 * terminology here we refer to the EID has being the node
	 * within the URI. For example, URI dtn://node.dtn/abcdef
	 * would have EID dtn://node.dtn.
	 * 
	 * @return The EID.
	 */
	string eidFromURI(string uri);

	map<string, Link*> routeMap;
	list<TemporalRoute * > temporalList;
	

	
};


#endif
